package com.xiaoye.digitaltwin.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xiaoye.digitaltwin.common.R;
import com.xiaoye.digitaltwin.entity.Baopo;
import com.xiaoye.digitaltwin.entity.Student;
import com.xiaoye.digitaltwin.service.BaopoService;
import com.xiaoye.digitaltwin.service.StudentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * 爆破实验表
 * <p>
 * 爆破实验表 前端控制器
 * </p>
 *
 * @author xiaoye
 * @since 2023-04-01
 */
@Slf4j
@RestController
@RequestMapping("/baopo")
public class BaopoController {

    @Autowired
    private BaopoService baopoService;

    @Autowired
    private StudentService studentService;

    @Value("${digital.path.baopo.basepath}")
    private String basePath;

    @Value("${digital.path.baopo.report}")
    private String uploadReports;

    /**
     * 根据传入的七个值  三个外径  三个壁厚    实时压力值
     * 计算出位移云图，应变云图  以及压力-容积变化量图
     * 并存入数据库
     * @param baopo
     * @param request
     * @return
     */
    @PostMapping("/compute")
    public R<String> handleData(@RequestBody Baopo baopo, HttpServletRequest request){


        if (baopo.getStress() == null) {
            return R.error("压力不能为空");
        }
        if (baopo.getOuterDiameter1() == null || baopo.getOuterDiameter2() == null || baopo.getOuterDiameter3() == null) {
            return R.error("外径不能为空");
        }
        if (baopo.getWallThick1() == null || baopo.getWallThick2() == null || baopo.getWallThick3() == null) {
            return R.error("壁厚不能为空");
        }

        if(baopo.getOuterDiameter1() < 45.0 || baopo.getOuterDiameter1()> 46.0){
            return R.error("外径值1不再规定范围");
        }


        //数据校验
        String checked = baopoService.check(baopo);
        if(!checked.equals("通过")){
            return R.error(checked);
        }

        //求外径平均   45.0  45.6
        double aveOD = (baopo.getOuterDiameter1() + baopo.getOuterDiameter2() + baopo.getOuterDiameter3()) / 3;

        //求平均壁厚   3.80  3.90
        double aveWT  = (baopo.getWallThick1() + baopo.getWallThick2() + baopo.getWallThick3()) / 3;

        String formatOD = formatOD(aveOD);
        String formatWT = formatWT(aveWT);

        //确定文件夹名称
        String folder = formatOD + "-" + formatWT;

        //确定压力值
        String formatStress = formatStress(baopo.getStress());

        String weiyi = folder + File.separator + "weiyiyuntu" + File.separator + "weiyi" + formatStress + ".jpeg";
        String yingbian = folder + File.separator + "yingbianyuntu" + File.separator + "yingbian" + formatStress + ".jpeg";
        String strvol = folder + File.separator + "压力-容积变化量图数据列表.txt";
        String download = folder + File.separator + "实验数据下载.zip";

        String stuId = request.getSession().getAttribute("studentId").toString();
        //获取学生学号
        Student stu = studentService.getById(stuId);
        String stuNo = stu.getStuNo();

        baopo.setWeiyiPic(weiyi);
        baopo.setYingbianPic(yingbian);
        baopo.setStressVolumePic(strvol);
        baopo.setDownload(download);
        baopo.setStuNo(stuNo);

        //查询爆破表中是否存在数据
        LambdaQueryWrapper<Baopo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Baopo::getStuNo,stuNo);
        Baopo baopoStu = baopoService.getOne(queryWrapper);
        if (baopoStu == null) {
            baopoService.save(baopo);
        }else {
            baopoStu.setWeiyiPic(weiyi);
            baopoStu.setYingbianPic(yingbian);
            baopoStu.setStressVolumePic(strvol);
            baopoStu.setDownload(download);
            baopoService.updateById(baopoStu);
        }

        return R.success("数据处理成功");
    }

    /**
     * 返回位移云图
     * @param request
     * @return
     */
    @GetMapping("/weiyi")
    public R<String> returnWeiyi(HttpServletRequest request){
        String stuId = request.getSession().getAttribute("studentId").toString();
        //获取学生学号
        Student stu = studentService.getById(stuId);
        String stuNo = stu.getStuNo();

        //从爆破表查询该学生对应记录
        LambdaQueryWrapper<Baopo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Baopo::getStuNo,stuNo);
        Baopo baopoStu = baopoService.getOne(queryWrapper);

        //出现异常导致爆破表没有数据
        if (baopoStu == null)
            return R.error("数据库暂无数据");

        String weiyiPic = baopoStu.getWeiyiPic();
        return R.success(weiyiPic);
    }

    /**
     * 返回应变云图
     * @param request
     * @return
     */
    @GetMapping("/yingbian")
    public R<String> returYingbian(HttpServletRequest request){
        String stuId = request.getSession().getAttribute("studentId").toString();
        //获取学生学号
        Student stu = studentService.getById(stuId);
        String stuNo = stu.getStuNo();

        //从爆破表查询该学生对应记录
        LambdaQueryWrapper<Baopo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Baopo::getStuNo,stuNo);
        Baopo baopoStu = baopoService.getOne(queryWrapper);

        //出现异常导致爆破表没有数据
        if (baopoStu == null)
            return R.error("数据库暂无数据");
        String yingbianPic = baopoStu.getYingbianPic();
        return R.success(yingbianPic);
    }

    /**
     * 返回压力-容积变化量图
     *
     * @param request
     * @return
     */
    @GetMapping("/strvol")
    public R<Map<String, String>> returStressVolume(HttpServletRequest request) throws FileNotFoundException {
        String stuId = request.getSession().getAttribute("studentId").toString();
        //获取学生学号
        Student stu = studentService.getById(stuId);
        String stuNo = stu.getStuNo();

        //从爆破表查询该学生对应记录
        LambdaQueryWrapper<Baopo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Baopo::getStuNo,stuNo);
        Baopo baopoStu = baopoService.getOne(queryWrapper);

        //出现异常导致爆破表没有数据
        if (baopoStu == null)
            return R.error("数据库暂无数据");
        String stressVolumePic = baopoStu.getStressVolumePic();
        String baseUrl = "E:\\Project\\DigitalTwinPic\\baopo\\";
        String filePath = baseUrl + stressVolumePic;
//        String filePath = "E:\\Project\\DigitalTwinPic\\waiya\\127.6\\52.5\\127.6-52.5-0.24-0.01\\载荷—位移数据列表.txt";
        double[] a;
        double[] b;


        File file = new File(filePath);
        Scanner scanner = new Scanner(file);

        int lines = 0;
        while (scanner.hasNextLine()) {
            scanner.nextLine();
            lines++;
        }

        a = new double[lines];
        b = new double[lines];

        scanner = new Scanner(file);
        int index = 0;

        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();

            if (!line.isEmpty()) {
                String[] values = line.split(" ");

                a[index] = Double.parseDouble(values[0]);
                b[index] = Double.parseDouble(values[1]);

                index++;
            }
        }

        // 将数组转换为字符串形式
        String arrayAStr = Arrays.toString(a);
        String arrayBStr = Arrays.toString(b);

        // 创建 Map 并返回
        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("arrayB", arrayBStr);
        resultMap.put("arrayA", arrayAStr);

        return R.success(resultMap);
//        return R.success(stressVolumePic);
    }

    /**
     * 学生上传实验报告
     * @param request
     * @param file
     * @return
     */
    @PostMapping("/report")
    public R<String> uploadRepoet(HttpServletRequest request, MultipartFile file){
        //获取原始文件名
        String originalFilename = file.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));

        String studentId = request.getSession().getAttribute("studentId").toString();
        //查询学生学号
        Student stu = studentService.getById(studentId);
        String stuNo = stu.getStuNo();

        //将学号与文件后缀名拼接 组成唯一标识
        String reportname = stuNo + suffix;

        //将上传的文件保存在指定路径
        File dir = new File(uploadReports);
        if(!dir.exists()){
            //目录不存在，需要创建
            dir.mkdirs();
        }
        try {
            //将临时文件转存到指定位置
            file.transferTo(new File(uploadReports + reportname));
        } catch (IOException e) {
            e.printStackTrace();
            return R.error("报告上传失败");
        }

        LambdaUpdateWrapper<Baopo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Baopo::getStuNo,stuNo);
        updateWrapper.set(Baopo::getReport,reportname);
        baopoService.update(updateWrapper);
        return R.success("文件上传成功");
    }

    /**
     * 学生下载实验数据
     * @param request
     */
    @GetMapping("/data")
    public R<String> downloadData(HttpServletRequest request){
        String stuId = request.getSession().getAttribute("studentId").toString();
        //获取学生学号
        Student stu = studentService.getById(stuId);
        String stuNo = stu.getStuNo();

        //从爆破表查询该学生对应记录
        LambdaQueryWrapper<Baopo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Baopo::getStuNo,stuNo);
        Baopo baopoStu = baopoService.getOne(queryWrapper);

        //出现异常导致爆破表没有数据
        if (baopoStu == null)
            return R.error("数据库暂无数据");
        String download = baopoStu.getDownload();
        return R.success(download);
    }

    /**
     * 学生反馈信息
     * @param request
     * @param msg
     * @return
     */
    @PostMapping("/feedback")
    public R<String> feedback(HttpServletRequest request, String msg){
        String stuId = request.getSession().getAttribute("studentId").toString();
        //获取学生学号
        Student stu = studentService.getById(stuId);
        String stuNo = stu.getStuNo();

        LambdaUpdateWrapper<Baopo> updateWrapper= new LambdaUpdateWrapper<>();
        updateWrapper.eq(Baopo::getStuNo,stuNo);
        updateWrapper.set(Baopo::getFeedback,msg);
        baopoService.update(updateWrapper);
        return R.success("提交反馈成功");
    }

    /**
     * 格式化平均外径
     * @param aveOD
     * @return
     */
    private String formatOD(double aveOD){
        if (aveOD >= 45.0 && aveOD < 45.1){
            return "45.0";
        }else if (aveOD >= 45.1 && aveOD < 45.3){
            return "45.2";
        }else if (aveOD >= 45.3 && aveOD < 45.5){
            return "45.4";
        }else
            return "45.6";
    }

    /**
     * 格式化平均壁厚
     * @param aveWT
     * @return
     */
    private String formatWT(double aveWT){
        if(aveWT >= 3.80 && aveWT <3.81){
            return "3.80";
        }else if (aveWT >= 3.81 && aveWT <3.83){
            return "3.82";
        }else if (aveWT >= 3.83 && aveWT <3.85){
            return "3.84";
        }else if (aveWT >= 3.85 && aveWT <3.87){
            return "3.86";
        }else if (aveWT >= 3.87 && aveWT <3.89){
            return "3.88";
        }else
            return "3.90";
    }

    private String formatStress(double stress){
        //对压力进行四舍五入
        int num = (int) Math.round(stress);
        if (num %2 == 1){
            num--;
        }
        return Integer.toString(num);
    }
}
